#include "parsecandata.h"
#include <QGlobalStatic>
#include <QDebug>
#include <QPixmap>
#include <QDateTime>
#include <QtConcurrent>
#include "common.h"
#include "quiwidget.h"
#include "selfform.h"
#include "alarmdashboard.h"
#include "mainscene.h"

Q_GLOBAL_STATIC(ParseCANData,m_instance)

QString swapHL(const QString &data)
{
    QString resultData;
    for(int i = data.count(); i > 0 ; i--)
    {
        resultData += data.at(i-1);
    }

    return resultData;
}

QString splitBynary(int startByte,int startBit,int length,const QStringList &binaryList)
{
    //cQStringList resultData;
    QString sourceBits;
    if(binaryList.count() !=8 )
    {
        return {};
    }

    int size = binaryList.count();
    for(int i = 0; i < size ; i++)
    {
        QString data = binaryList.at(i);
        for(int j = data.count(); j > 0; j--)
        {
            sourceBits.append(data.at(j-1));
        }
    }

    int sumLength = (startByte+1) * 8;
    QString tmpdata;
    if(length <= 8) {
        tmpdata = sourceBits.mid(startBit,length);
    }
    else {
        tmpdata = sourceBits.mid(startBit,sumLength - startBit);
    }

    QString swapdata;
    swapdata = swapHL(tmpdata);
    int i = 0;
    while(swapdata.length() < length) {
        i += 1;
        int c_length = length - swapdata.length();
        QString other_data = binaryList.at(startByte - i);
        QString c_data;
        if(c_length <= 8) {
            c_data = other_data.right(c_length);
        }
        else {
            c_data = other_data.right(8);
        }
        swapdata = c_data+swapdata;
    }

    return swapdata;
}

//str转二进制字符串
QString byteToBinaryString(const QString &strByte)
{
    //QString str = "AB";
    QByteArray utf8Data = strByte.toUtf8();
    QString binaryResult;
    for (char byte : utf8Data) {
        uchar uc = static_cast<uchar>(byte);
        // 将字节转为8位二进制，补前导零
        binaryResult += QString("%1").arg(uc, 8, 2, QLatin1Char('0'));
    }
    // 结果示例："0100000101000010" （A和B的UTF-8编码）
    return binaryResult;
}

//二进制字符串转10进制
int binaryStringToDecimal(const QString &binary)
{
    bool ok;
    int decimal = binary.toInt(&ok,2);
    if(ok){
        return decimal;
    }

    return -1; //转换失败-1
}

ParseCANData::ParseCANData(QObject *parent) : QObject(parent)
{
    m_timer = new QTimer();
    connect(m_timer,&QTimer::timeout,this,[&](){
        MainSceneIns->SetVolterB(m_candatas.battVolt);
        MainSceneIns->SetVolterP(m_candatas.linkVolt);
        emit flushUIBMS204(m_candatas.battVolt,m_candatas.battCurr,m_candatas.soc);     
        emit flushUIBMS208(m_candatas.data.value);
        if(alarm_208_flag){
            emit addAlarm(m_alarmData);
        }
        SelfFormIns->flushUIBMS208View(m_modeldata_208);

        emit flushUIBMS36A(m_candatas.maxCellVolt,m_candatas.minCellVolt,m_candatas.maxCvNO,m_candatas.minCvNO);

        emit flushUIBMS36B(m_candatas.maxCellTemp,m_candatas.maxCtNO,m_candatas.minCellTemp,m_candatas.minCtNO,m_candatas.avrgCellTemp);

        emit flushUIBMS35A(m_candatas.chgPwr,m_candatas.disChgPwr,m_candatas.chgAmount,m_candatas.disChgAmount);

        if(alarm_39B_flag){
            emit addAlarm(m_alarmData);
        }

        //emit flushUIBMS39B(m_modeldata_39B);

        emit flushUIVCU253(m_candatas.hV_bat_power_enable,m_candatas.vehicle_charge_state);

        SelfFormIns->flashBMS39AUI(m_candatas.tempNum,m_candatas.tempNo,m_candatas.tempVal,m_candatas.cellNum,m_candatas.cvNO,m_candatas.cellVolt);
    });

    m_timer->start(500);
}

ParseCANData *ParseCANData::Instance()
{
    return m_instance;
}

void ParseCANData::parseBMS204(const QStringList &frame)
{
    // 解析 BattVolt（电池组总电压）
    quint32 BattVolt = extractSignal(frame, 1, 10, 14);
    m_candatas.battVolt = BattVolt * 0.1; // 精度为 0.1

    // 解析 LinkVolt（电池包端口电压）
    quint32 LinkVolt = extractSignal(frame, 3, 28, 14);
    m_candatas.linkVolt = LinkVolt * 0.1; // 精度为 0.1

    // 解析 BattCurr（电池组总电流）
    quint32 BattCurr = extractSignal(frame, 5, 46, 14);
    m_candatas.battCurr = (BattCurr * 0.1) - 400; // 精度为 0.1，偏移量为 -400


    // 解析 SOC（电池电量状态）
    quint32 SOC = extractSignal(frame, 6, 52, 10);
    m_candatas.soc = SOC * 0.1; // 精度为 0.1
}

void ParseCANData::parseBMS208(const QStringList &frame)
{
    m_modeldata_208.clear();
    // 解析 绝缘电阻值
    quint32 InsResVal = extractSignal(frame, 1, 8, 16);
    m_candatas.data.name = "绝缘电阻值";
    m_candatas.data.value = static_cast<int>(InsResVal);
    m_candatas.data.description = "KΩ";
    m_modeldata_208.push_back(m_candatas.data);

    BMS_Normal itemData;
    // 解析 BMS故障等级
    quint32 FaultLevel = extractSignal(frame, 2, 21, 3);
    itemData.name = "BMS故障等级";
    itemData.value = static_cast<int>(FaultLevel);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "无故障";
        alarm_208_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "一级故障";
        m_alarmData.message = "BMS故障一级告警";
        m_alarmData.reason = "系统出现故障";
        m_alarmData.solution = "请立即断电，返厂维修";
        m_alarmData.iconPath = ":/image/info.png";
        m_alarmData.level = 0;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

        alarm_208_flag = true;
        //        QtConcurrent::run([=]{
//            QTimer::singleShot(3000,[=](){
//                emit addAlarm(m_alarmData);
//            });
//        });
    }
        break;
    case 2:
    {
        itemData.description = "二级故障";
        m_alarmData.message = "BMS故障二级告警";
        m_alarmData.reason = "系统出现故障";
        m_alarmData.solution = "请立即断电，返厂维修";
        m_alarmData.iconPath = ":/image/warning.png";
        m_alarmData.level = 1;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_208_flag = true;
        //        QtConcurrent::run([=]{
//            QTimer::singleShot(3000,[=](){
//                emit addAlarm(m_alarmData);
//            });
//        });
    }
        break;
    case 3:
    {
        itemData.description = "三级故障";
        m_alarmData.message = "BMS故障三级告警";
        m_alarmData.reason = "系统出现故障";
        m_alarmData.solution = "请立即断电，返厂维修";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_208_flag = true;
        //        QtConcurrent::run([=]{
//            QTimer::singleShot(3000,[=](){
//                emit addAlarm(m_alarmData);
//            });
//        });
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_208_flag = false;
    }
        break;
    }
    m_modeldata_208.push_back(itemData);



    // 解析 BMS工作状态
    quint32 WorkStatus = extractSignal(frame, 2, 18, 3);
    itemData.name = "BMS工作状态";
    itemData.value = static_cast<int>(WorkStatus);
    switch (itemData.value) {
    case 0:
        itemData.description = "初始化";
        break;
    case 1:
        itemData.description = "待机";
        break;
    case 2:
        itemData.description = "预充电";
        break;
    case 3:
        itemData.description = "高压上电完成";
        break;
    case 4:
        itemData.description = "高压下电";
        break;
    case 5:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 预充电状态
    quint32 PreChgSt = extractSignal(frame, 2, 16, 2);
    itemData.name = "预充电状态";
    itemData.value = static_cast<int>(PreChgSt);
    switch (itemData.value) {
    case 0:
        itemData.description = "未预充";
        break;
    case 1:
        itemData.description = "正在预充";
        break;
    case 2:
        itemData.description = "预充完成";
        break;
    case 3:
        itemData.description = "预充失败";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 动力电池充电状态
    quint32 ChgStatus = extractSignal(frame, 3, 30, 2);
    itemData.name = "动力电池充电状态";
    itemData.value = static_cast<int>(ChgStatus);
    switch (itemData.value) {
    case 0:
        itemData.description = "未充电";
        break;
    case 1:
        itemData.description = "正在充电";
        break;
    case 2:
        itemData.description = "充电完成";
        break;
    case 3:
        itemData.description = "充电中止";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 风扇接触器状态
    quint32 FSRelaySt = extractSignal(frame, 3, 29, 1);
    itemData.name = "风扇接触器状态";
    itemData.value = static_cast<int>(FSRelaySt);
    switch (itemData.value) {
    case 0:
        itemData.description = "断开";
        break;
    case 1:
        itemData.description = "闭合";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 正极接触器状态
    quint32 PosRelaySt = extractSignal(frame, 3, 28, 1);
    itemData.name = "正极接触器状态";
    itemData.value = static_cast<int>(PosRelaySt);
    switch (itemData.value) {
    case 0:
        itemData.description = "断开";
        break;
    case 1:
        itemData.description = "闭合";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 预充接触器状态
    quint32 PreRelaySt = extractSignal(frame, 3, 27, 1);
    itemData.name = "预充接触器状态";
    itemData.value = static_cast<int>(PreRelaySt);
    switch (itemData.value) {
    case 0:
        itemData.description = "断开";
        break;
    case 1:
        itemData.description = "闭合";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 快充接触器状态
    quint32 DCChgRelaySt = extractSignal(frame, 3, 26, 1);
    itemData.name = "快充接触器状态";
    itemData.value = static_cast<int>(DCChgRelaySt);
    switch (itemData.value) {
    case 0:
        itemData.description = "断开";
        break;
    case 1:
        itemData.description = "闭合";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 负极接触器状态
    quint32 NegRelaySt = extractSignal(frame, 3, 25, 1);
    itemData.name = "负极接触器状态";
    itemData.value = static_cast<int>(NegRelaySt);
    switch (itemData.value) {
    case 0:
        itemData.description = "断开";
        break;
    case 1:
        itemData.description = "闭合";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 高压上电请求
    quint32 HvCtrlReq = extractSignal(frame, 3, 24, 1);
    itemData.name = "高压上电请求";
    itemData.value = static_cast<int>(HvCtrlReq);
    switch (itemData.value) {
    case 0:
        itemData.description = "无请求";
        break;
    case 1:
        itemData.description = "有请求";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);

    // 解析 BMS工作模式
    quint32 BMS_Mode = extractSignal(frame, 4, 36, 3);
    itemData.name = "BMS工作模式";
    itemData.value = static_cast<int>(BMS_Mode);
    switch (itemData.value) {
    case 0:
        itemData.description = "无工作模式";
        break;
    case 1:
        itemData.description = "常规模式";
        break;
    case 2:
        itemData.description = "外接交流充电模式";
        break;
    case 3:
        itemData.description = "外接直流充电模式";
        break;
    case 4:
        itemData.description = "外接放电模式";
        break;
    case 5:
        itemData.description = "预约交流充电模式";
        break;
    case 6:
        itemData.description = "智能12V充电模式";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_208.push_back(itemData);
}

void ParseCANData::parseBMS36A(const QStringList &frame)
{
    // 解析 最高单体电压
    quint32 MaxCellVolt = extractSignal(frame, 1, 8, 16);
    m_candatas.maxCellVolt = MaxCellVolt * 1.0;


    // 解析 最低单体电压
    quint32 MinCellVolt = extractSignal(frame, 3, 24, 16);
    m_candatas.minCellVolt = MinCellVolt * 1.0;

    // 解析 电池健康状态
    quint32 SOH = extractSignal(frame, 4, 34, 6);
    m_candatas.sOH = SOH * 1.0 + 80;

    // 解析 最高单体电压位置
    quint32 MaxCvNO = extractSignal(frame, 5, 40, 8);
    m_candatas.maxCvNO = MaxCvNO * 1.0 + 1;


    // 解析 最低单体电压位置
    quint32 MinCvNO = extractSignal(frame, 6, 48, 8);
    m_candatas.minCvNO = MinCvNO * 1.0 + 1;
}

void ParseCANData::parseBMS36B(const QStringList &frame)
{
    //最高电芯温度
    quint32 MaxCellTemp = extractSignal(frame, 0, 0, 8);
    m_candatas.maxCellTemp = MaxCellTemp * 1.0 - 40;

    //最高温度位置
    quint32 MaxCtNO = extractSignal(frame, 1, 8, 8);
    m_candatas.maxCtNO = MaxCtNO * 1.0 + 1;

    //最低电芯温度
    quint32 MinCellTemp = extractSignal(frame, 2, 16, 8);
    m_candatas.minCellTemp = MinCellTemp * 1.0 - 40;

    //最低温度位置
    quint32 MinCtNO = extractSignal(frame, 3, 24, 8);
    m_candatas.minCtNO = MinCtNO * 1.0 + 1;

    //平均电芯温度
    quint32 AvrgCellTemp = extractSignal(frame, 4, 32, 8);
    m_candatas.avrgCellTemp = AvrgCellTemp * 1.0 - 40;
}

void ParseCANData::parseBMS35A(const QStringList &frame)
{
    //外接充电功率
    quint32 ChgPwr = extractSignal(frame, 0, 0, 8);
    m_candatas.chgPwr = ChgPwr * 1.0;


    //外接放电功率
    quint32 DisChgPwr = extractSignal(frame, 1, 8, 8);
    m_candatas.disChgPwr = DisChgPwr * 1.0;


    //已充电电量
    quint32 ChgAmount = extractSignal(frame, 7, 56, 10);
    m_candatas.chgAmount = ChgAmount * 0.1 ;


    //已放电电量
    quint32 DisChgAmount = extractSignal(frame, 5, 40, 10);
    m_candatas.disChgAmount = DisChgAmount * 0.1;


    //充电完成剩余时间
    quint32 ChgFinishRemainTime = extractSignal(frame, 2, 16, 8);
    m_candatas.chgFinishRemainTime = ChgFinishRemainTime * 0.1;
}

void ParseCANData::parseBMS39B(const QStringList &frame)
{
    m_modeldata_39B.clear();
    BMS_Normal itemData;
    //  SOC过高报警
    quint32 SOC_Over_Alarm = extractSignal(frame, 0, 7, 1);
    itemData.name = "SOC过高报警";
    itemData.value = static_cast<int>(SOC_Over_Alarm);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // SOC跳变报警
    quint32 SOC_Transit_Alarm = extractSignal(frame, 0, 6, 1);
    itemData.name = "SOC跳变报警";
    itemData.value = static_cast<int>(SOC_Transit_Alarm);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 可充电储能系统匹配报警
    quint32 Chgable_Ensys_Matc_Alarm = extractSignal(frame, 0, 5, 1);
    itemData.name = "可充电储能系统匹配报警";
    itemData.value = static_cast<int>(Chgable_Ensys_Matc_Alarm);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 单体过压
    quint32 Cell_Over_Volt = extractSignal(frame, 5, 44, 2);
    itemData.name = "单体过压";
    itemData.value = static_cast<int>(Cell_Over_Volt);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        alarm_39B_flag = false;
        break;
    case 1:
    {
        itemData.description = "二级故障";
        m_alarmData.message = "单体过压一级告警";
        m_alarmData.reason = "单体过放或采样线松动";
        m_alarmData.solution = "正常充电到过高时不予处理；异常出现时排查线束和电芯";
        m_alarmData.iconPath = ":/image/warning.png";
        m_alarmData.level = 1;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

        alarm_39B_flag = true;
    }
        break;
    case 2:
    {
        itemData.description = "三级故障";
        m_alarmData.message = "单体过压二级告警";
        m_alarmData.reason = "单体过放或采样线松动";
        m_alarmData.solution = "正常充电到过高时不予处理；异常出现时排查线束和电芯";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    case 3:
        itemData.description = "预留";
        alarm_39B_flag = false;
        break;
    default:
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
        break;
    }
    m_modeldata_39B.push_back(itemData);


    // 单体欠压
    quint32 Cell_Under_Volt = extractSignal(frame, 0, 2, 2);
    itemData.name = "单体欠压";
    itemData.value = static_cast<int>(Cell_Under_Volt);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "一级故障";
        m_alarmData.message = "单体欠压一级告警";
        m_alarmData.reason = "单体过放或采样线松动";
        m_alarmData.solution = "正常放电到过低时不予处理；异常出现时排查线束和电芯";
        m_alarmData.iconPath = ":/image/warning.png";
        m_alarmData.level = 1;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    case 2:
    {
        itemData.description = "二级故障";
        m_alarmData.message = "单体欠压二级告警";
        m_alarmData.reason = "单体过放或采样线松动";
        m_alarmData.solution = "正常放电到过低时不予处理；异常出现时排查线束和电芯";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    case 3:
    {
        itemData.description = "三级故障";
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 总电压过压
    quint32 Bat_Over_Volt = extractSignal(frame, 0, 1, 1);
    itemData.name = "总电压过压";
    itemData.value = static_cast<int>(Bat_Over_Volt);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 总电压欠压
    quint32 Bat_Under_Volt = extractSignal(frame, 0, 0, 1);
    itemData.name = "总电压欠压";
    itemData.value = static_cast<int>(Bat_Under_Volt);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 单体压差大
    quint32 Cell_Delt_Volt_err = extractSignal(frame, 2, 23, 1);
    itemData.name = "单体压差大";
    itemData.value = static_cast<int>(Cell_Delt_Volt_err);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "单体压差过大二级告警";
        m_alarmData.reason = "电芯容量不一致,压差过大";
        m_alarmData.solution = "轻微警告，可以忽略";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 过流故障
    quint32 Chg_Over_Current = extractSignal(frame, 2, 21, 2);
    itemData.name = "过流故障";
    itemData.value = static_cast<int>(Chg_Over_Current);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "二级故障";
        break;
    case 2:
        itemData.description = "三级故障";
        break;
    case 3:
        itemData.description = "预留";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 温度过高
    quint32 Temp_High = extractSignal(frame, 5, 42, 2);
    itemData.name = "温度过高";
    itemData.value = static_cast<int>(Temp_High);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "二级故障";
        m_alarmData.message = "电池高温一级告警";
        m_alarmData.reason = "温度过高";
        m_alarmData.solution = "轻微警告，可以忽略";
        m_alarmData.iconPath = ":/image/warning.png";
        m_alarmData.level = 1;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    case 2:
    {
        itemData.description = "三级故障";
        m_alarmData.message = "电池高温二级告警";
        m_alarmData.reason = "温度过高";
        m_alarmData.solution = "轻微警告，可以忽略";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    case 3:
    {
        itemData.description = "预留";
        alarm_39B_flag = false;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 温度过低
    quint32 Temp_Low = extractSignal(frame, 2, 19, 1);
    itemData.name = "温度过低";
    itemData.value = static_cast<int>(Temp_Low);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "电池低温告警";
        m_alarmData.reason = "温度过低";
        m_alarmData.solution = "轻微警告，可以忽略";
        m_alarmData.iconPath = ":/image/warning.png";
        m_alarmData.level = 1;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 温差过大
    quint32 Delt_Temp_err = extractSignal(frame, 2, 18, 1);
    itemData.name = "温差过大";
    itemData.value = static_cast<int>(Delt_Temp_err);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "电池温差过大一级告警";
        m_alarmData.reason = "电池温差过大";
        m_alarmData.solution = "轻微警告，可以忽略";
        m_alarmData.iconPath = ":/image/warning.png";
        m_alarmData.level = 1;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // SOC过低
    quint32 SOC_Low = extractSignal(frame, 2, 17, 1);
    itemData.name = "SOC过低";
    itemData.value = static_cast<int>(SOC_Low);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "电池组SOC过低一级告警";
        m_alarmData.reason = "SOC过低";
        m_alarmData.solution = "轻微警告，可以忽略";
        m_alarmData.iconPath = ":/image/warning.png";
        m_alarmData.level = 1;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 绝缘故障
    quint32 Insulation_Fault = extractSignal(frame, 5, 40, 2);
    itemData.name = "绝缘故障";
    itemData.value = static_cast<int>(Insulation_Fault);
    double insulation_Fault = itemData.value;
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:        
    {
        itemData.description = "二级故障";
        m_alarmData.message = "绝缘故障一级告警";
        m_alarmData.reason = "电池包进水、高压线对地短路等造成绝缘故障";
        m_alarmData.solution = "检查电池包";
        m_alarmData.iconPath = ":/image/warning.png";
        m_alarmData.level = 1;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    case 2:
    {
        itemData.description = "三级故障";
        m_alarmData.message = "绝缘故障二级告警";
        m_alarmData.reason = "电池包进水、高压线对地短路等造成绝缘故障";
        m_alarmData.solution = "检查电池包";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    case 3:
    {
        itemData.description = "预留";
        alarm_39B_flag = false;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 高压互锁故障
    quint32 BMS_Interlock_Fault = extractSignal(frame, 3, 31, 1);
    itemData.name = "高压互锁故障";
    itemData.value = static_cast<int>(BMS_Interlock_Fault);
    double bms_Interlock_Fault = itemData.value;
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "高压互锁故障";
        m_alarmData.reason = "高压回路开路、MSD未插入或连接不良";
        m_alarmData.solution = "检测高压回路及MSD";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    emit flushUIBMS39B(insulation_Fault,bms_Interlock_Fault);
    // 外部通信失败
    quint32 Ext_Com_Fault = extractSignal(frame, 3, 29, 1);
    itemData.name = "外部通信失败";
    itemData.value = static_cast<int>(Ext_Com_Fault);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 内部通信失败
    quint32 Int_Com_Fault = extractSignal(frame, 3, 28, 1);
    itemData.name = "内部通信失败";
    itemData.value = static_cast<int>(Int_Com_Fault);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 电机预充失败
    quint32 Motor_Prechg_Fault = extractSignal(frame, 3, 27, 1);
    itemData.name = "电机预充失败";
    itemData.value = static_cast<int>(Motor_Prechg_Fault);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "预充电失败告警";
        m_alarmData.reason = "预充电压没达到预期值";
        m_alarmData.solution = "检查预充继电器或高压回路";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 电压检测故障
    quint32 Volt_Detect_Fault = extractSignal(frame, 3, 26, 1);
    itemData.name = "电压检测故障";
    itemData.value = static_cast<int>(Volt_Detect_Fault);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 电流检测故障
    quint32 Curr_Detect_Fault = extractSignal(frame, 3, 25, 1);
    itemData.name = "电流检测故障";
    itemData.value = static_cast<int>(Curr_Detect_Fault);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 温度检测故障
    quint32 Temp_Detect_Fault = extractSignal(frame, 3, 24, 1);
    itemData.name = "温度检测故障";
    itemData.value = static_cast<int>(Temp_Detect_Fault);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 正极接触器故障
    quint32 Pos_Rly_Fault = extractSignal(frame, 4, 39, 1);
    itemData.name = "正极接触器故障";
    itemData.value = static_cast<int>(Pos_Rly_Fault);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "主正极继电器粘连故障";
        m_alarmData.reason = "继电器粘连，继电器损坏。";
        m_alarmData.solution = "检查继电器";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 负极接触器故障
    quint32 Neg_Rly_Fault = extractSignal(frame, 4, 38, 1);
    itemData.name = "负极接触器故障";
    itemData.value = static_cast<int>(Neg_Rly_Fault);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "负极继电器粘连故障";
        m_alarmData.reason = "继电器粘连，继电器损坏。";
        m_alarmData.solution = "检查继电器";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 预充接触器故障
    quint32 Prechg_Rly_Fault = extractSignal(frame, 4, 37, 1);
    itemData.name = "预充接触器故障";
    itemData.value = static_cast<int>(Prechg_Rly_Fault);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "预充继电器粘连故障";
        m_alarmData.reason = "继电器粘连，继电器损坏。";
        m_alarmData.solution = "检查继电器";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 风扇接触器故障
    quint32 Fan_Rly_Fault = extractSignal(frame, 4, 36, 1);
    itemData.name = "风扇接触器故障";
    itemData.value = static_cast<int>(Fan_Rly_Fault);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "风扇接触器故障";
        m_alarmData.reason = "继电器粘连，继电器损坏。";
        m_alarmData.solution = "检查继电器";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 快充接触器故障
    quint32 FastChg_Rly_Fault = extractSignal(frame, 4, 35, 1);
    itemData.name = "快充接触器故障";
    itemData.value = static_cast<int>(FastChg_Rly_Fault);
    switch (itemData.value) {
    case 0:
    {
        itemData.description = "正常";
        alarm_39B_flag = false;
    }
        break;
    case 1:
    {
        itemData.description = "故障";
        m_alarmData.message = "快充继电器粘连故障";
        m_alarmData.reason = "继电器粘连，继电器损坏。";
        m_alarmData.solution = "检查继电器";
        m_alarmData.iconPath = ":/image/error.png";
        m_alarmData.level = 2;
        m_alarmData.timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        alarm_39B_flag = true;
    }
        break;
    default:
    {
        itemData.description = "无效NAN";
        alarm_39B_flag = false;
    }
        break;
    }
    m_modeldata_39B.push_back(itemData);

    // 直流充电口过温故障
    quint32 DC_ChgPort_OverTemp = extractSignal(frame, 6, 54, 2);
    itemData.name = "直流充电口过温故障";
    itemData.value = static_cast<int>(DC_ChgPort_OverTemp);
    switch (itemData.value) {
    case 0:
        itemData.description = "正常";
        break;
    case 1:
        itemData.description = "一级故障";
        break;
    case 2:
        itemData.description = "二级故障";
        break;
    case 3:
        itemData.description = "三级故障";
        break;
    default:
        itemData.description = "无效NAN";
        break;
    }
    m_modeldata_39B.push_back(itemData);
}

void ParseCANData::parseVCU253(const QStringList &frame)
{
    //高压母线电压（HCU取自MCU）
    quint32 HV_bus_voltg = extractSignal(frame, 1, 11, 13);
    m_candatas.hV_bus_voltg = HV_bus_voltg * 0.1;

    //电池工作使能
    quint32 HV_bat_power_enable = extractSignal(frame, 1, 9, 2);
    m_candatas.hV_bat_power_enable = static_cast<int>(HV_bat_power_enable);

    //系统可充电状态
    quint32 Vehicle_charge_state = extractSignal(frame, 1, 8, 1);
    m_candatas.vehicle_charge_state = static_cast<int>(Vehicle_charge_state) ;
}

void ParseCANData::parseBMS205(const QStringList &frame)
{
    // 解析峰值放电功率
    quint32 PeakDisPwr = extractSignal(frame, 1, 12, 12);
    m_candatas.peakDisPwr = PeakDisPwr * 0.1; // 精度为 0.1

    // 解析持续放电功率
    quint32 CtnDisPwr = extractSignal(frame, 2, 16, 12);
    m_candatas.ctnDisPwr = CtnDisPwr * 0.1; // 精度为 0.1

    // 解析峰值充电功率
    quint32 PeakChgPwr = extractSignal(frame, 4, 36, 12);
    m_candatas.peakChgPwr = PeakChgPwr * 0.1; // 精度为 0.1

    // 解析持续充电功率
    quint32 CtnChgPwr = extractSignal(frame, 5, 40, 12);
    m_candatas.ctnChgPwr = CtnChgPwr * 0.1; // 精度为 0.1
}

void ParseCANData::parseBMS38A(const QStringList &frame)
{
    // 充电需求电流
    quint32 ChgReqCurr = extractSignal(frame, 1, 12, 12);
    m_candatas.chgReqCurr = ChgReqCurr * 0.1;

    // 充电需求电压
    quint32 ChgReqVolt = extractSignal(frame, 3, 31, 13);
    m_candatas.chgReqVolt = ChgReqVolt * 0.1;

    // 充电线缆额定充电电流
    quint32 ChgCablCrr = extractSignal(frame, 5, 45, 3);
    m_candatas.chgCablCrr = ChgCablCrr * 1.0;

    // 供电设备最大允许充电电流
    quint32 MaxallwCrr = extractSignal(frame, 6, 51, 10);
    m_candatas.maxallwCrr = MaxallwCrr * 0.1 + 6;

    //CC2状态
    quint32 CC2Sta = extractSignal(frame, 7, 61, 1);
    m_candatas.cC2Sta = static_cast<int>(CC2Sta);
}

void ParseCANData::parseBMS39A(const QStringList &frame)
{
    // 温度总数
    quint32 TempNum = extractSignal(frame, 0, 0, 8);
    m_candatas.tempNum = static_cast<int>(TempNum) + 1;

    // 温度编号
    quint32 TempNo = extractSignal(frame, 1, 8, 8);
    m_candatas.tempNo = static_cast<int>(TempNo) + 1;

    // 温度值
    quint32 TempVal = extractSignal(frame, 2, 16, 8);
    m_candatas.tempVal = TempVal * 1.0 - 40;

    // 电芯串数
    quint32 CellNum = extractSignal(frame, 3, 24, 8);
    m_candatas.cellNum = static_cast<int>(CellNum) + 1;

    //电芯电压编号
    quint32 CvNO = extractSignal(frame, 4, 32, 8);
    m_candatas.cvNO = static_cast<int>(CvNO) + 1;

    //单体电芯电压
    quint32 CellVolt = extractSignal(frame, 6, 48, 16);
    m_candatas.cellVolt = CellVolt * 0.001;
}

void ParseCANData::parseBMS37B(const QStringList &frame)
{
    // BMS硬件版本标识（H）
    quint32 BMS_HW_Version_Sign = extractSignal(frame, 0, 0, 8);
    m_candatas.bMS_HW_Version_Sign = static_cast<int>(BMS_HW_Version_Sign);

    // BMS硬件版本号（001～999）
    quint32 BMS_HW_Version = extractSignal(frame, 3, 24, 24);
    m_candatas.bMS_HW_Version = static_cast<int>(BMS_HW_Version );

    // BMS软件版本号标识（S）
    quint32 BMS_SW_Version_Sign = extractSignal(frame, 4, 32, 8);
    m_candatas.bMS_SW_Version_Sign = static_cast<int>(BMS_SW_Version_Sign);

    // BMS软件版本号（001～999）
    quint32 BMS_SW_Version = extractSignal(frame, 7, 56, 24);
    m_candatas.bMS_SW_Version = static_cast<int>(BMS_SW_Version);
}

void ParseCANData::parseBMS3E4(const QStringList &frame)
{
    // 充电插枪次数
    quint32 Plug_times = extractSignal(frame, 1, 8, 16);
    m_candatas.plug_times = Plug_times * 1.0;

    // 总充电量统计
    quint32 Chg_Power_Cal = extractSignal(frame, 4, 34, 22);
    m_candatas.chg_Power_Cal = Chg_Power_Cal * 0.1;
}

quint32 ParseCANData::extractSignal(const QStringList &frame, int startByte, int startBit, int bitLength)
{
    //测试数据，得到8字节的每个二进制
    QStringList binaryList;
    for(int i = 0; i < frame.count(); i++)
    {
        QString tmpstr = frame.at(i);
        binaryList.append(QUIHelper::strHexToStrBin(tmpstr));

        //qDebug() << binaryList[i];
    }

//    QStringList datas = splitBynary(startByte,startBit,bitLength,binaryList);
//    QString data="";
//    for(int i = datas.count(); i > 0 ; i--)
//    {
//        data += datas.at(i-1);
//    }
    //qDebug() << "result binary: " << data;

    QString data = splitBynary(startByte,startBit,bitLength,binaryList);
    int decimal = binaryStringToDecimal(data);
    //qDebug() << "result decimal: " << decimal;

    return decimal;
}
